<template>
  <view class="index-container">
    <!-- 历史会话侧边栏 - 使用 uv-ui popup 组件 -->
    <uv-popup
      ref="sessionPopup"
      mode="left"
      :close-on-click-overlay="true"
      :overlay-opacity="0.4"
      bg-color="none"
      @change="onPopupChange"
    >
      <view class="drawer-container">
        <!-- 侧边栏头部 -->
        <view class="drawer-header">
          <text class="drawer-title">历史会话</text>
          <view class="close-btn" @click="closeSessionDrawer">
            <uv-icon name="close" size="24" color="#666"></uv-icon>
          </view>
        </view>

        <!-- 会话列表 -->
        <scroll-view class="session-list" scroll-y>
          <!-- 今天的会话 -->
          <view v-if="todaySessions.length > 0" class="session-group">
            <view class="group-title">今天</view>
            <view
              v-for="session in todaySessions"
              :key="session.sessionId"
              class="session-item"
              :class="{ active: session.sessionId === currentSessionId }"
              @click="openSession(session.sessionId, session.title)"
            >
              <view class="session-content">
                <text class="session-title">{{ session.title || '未命名会话' }}</text>
                <text class="session-time">{{ formatTime(session.createTime) }}</text>
              </view>
              <!-- <view class="delete-btn" @click.stop="deleteSession(session.sessionId)">
                <uv-icon name="trash" size="25" color="#999"></uv-icon>
              </view> -->
            </view>
          </view>

          <!-- 昨天的会话 -->
          <view v-if="yesterdaySessions.length > 0" class="session-group">
            <view class="group-title">昨天</view>
            <view
              v-for="session in yesterdaySessions"
              :key="session.sessionId"
              class="session-item"
              :class="{ active: session.sessionId === currentSessionId }"
              @click="openSession(session.sessionId, session.title)"
            >
              <view class="session-content">
                <text class="session-title">{{ session.title || '未命名会话' }}</text>
                <text class="session-time">{{ formatTime(session.createTime) }}</text>
              </view>
              <!-- <view class="delete-btn" @click.stop="deleteSession(session.sessionId)">
                <uv-icon name="trash" size="18" color="#999"></uv-icon>
              </view> -->
            </view>
          </view>

          <!-- 前七天的会话 -->
          <view v-if="recentSessions.length > 0" class="session-group">
            <view class="group-title">前七天</view>
            <view
              v-for="session in recentSessions"
              :key="session.sessionId"
              class="session-item"
              :class="{ active: session.sessionId === currentSessionId }"
              @click="openSession(session.sessionId, session.title)"
            >
              <view class="session-content">
                <text class="session-title">{{ session.title || '未命名会话' }}</text>
                <text class="session-time">{{ formatTime(session.createTime) }}</text>
              </view>
              <!-- <view class="delete-btn" @click.stop="deleteSession(session.sessionId)">
                <uv-icon name="trash" size="18" color="#999"></uv-icon>
              </view> -->
            </view>
          </view>

          <!-- 空状态 -->
          <view
            v-if="todaySessions.length === 0 && yesterdaySessions.length === 0 && recentSessions.length === 0"
            class="empty-state"
          >
            <view class="empty-icon">
              <uv-icon name="chat" size="48" color="#d0d0d0"></uv-icon>
            </view>
            <text class="empty-text">暂无历史会话</text>
            <text class="empty-desc">开始新的对话吧</text>
          </view>  
        </scroll-view>
      </view>
    </uv-popup>

    <!-- 热门山寨币选择器 -->
    <custom-picker
      ref="altcoinsPicker"
      :columns="altcoinsColumns"
      :default-index="selectedAltcoinIndex"
      title="选择策略"
      @confirm="onAltcoinConfirm"
      @cancel="onAltcoinCancel"
    ></custom-picker>

    <!-- 使用次数用完提示弹窗 -->
    <uv-modal
      ref="noCountModal"
      title="使用次数已用完"
      content="您今日的免费使用次数已经用完了，请改天再试，或者您直接在【我的-联系客服】获取更多权限。"
      :show-cancel-button="true"
      cancel-text="知道了"
      confirm-text="联系客服"
      confirm-color="#00d4aa"
      @confirm="goToCustomerService"
      @cancel="closeNoCountModal"
    ></uv-modal>

    <!-- 首次进入APP温馨提醒弹窗 -->
    <uv-modal
      ref="welcomeModal"
      title="温馨提醒"
      content="链智Quant AI已停止为 中国境内 用户提供相关服务，我们仍将继续致力于为全球用户(中国境内除外)提供高质量服务。"
      :show-cancel-button="false"
      confirm-text="我已知晓"
      confirm-color="#00d4aa"
      @confirm="handleWelcomeConfirm"
    ></uv-modal>

    <!-- 滚动内容区域 -->
    <z-paging
      ref="paging"
      v-model="messageList"
      use-chat-record-mode
      :safe-area-inset-bottom="false"
      :auto-full-height="true"
      :default-page-size="10"
      :auto-show-back-to-top="true"
      :refresher-enabled="true"
      :loading-more-enabled="true"
      :lower-threshold="50"
      @query="queryList"
      @keyboardHeightChange="keyboardHeightChange"
      @hidedKeyboard="hidedKeyboard"
    >
      <template #top>
        <view class="top-bg">
          <!-- 头部导航 -->
          <view class="header">
            <view class="header-content">
              <!-- 标题和次数 -->
              <view class="title-wrapper">
                <text class="header-title">新对话</text>
                <!-- 非会员显示可用次数 -->
                <view v-if="!isVip" class="usage-badge">
                  <text class="usage-text">可用 {{ remainingCount }} 次</text>
                </view>
              </view>

              <!-- 新建会话按钮 -->
              <view class="new-session-btn" @click="createNewSession">
                <image
                  src="/static/images/home/new-session.png"
                  class="new-session-icon"
                  mode="aspectFit"
                />
              </view>
            </view>
          </view>
          <view class="banner">
            <view class="banner-content"></view>
          </view>
        </view>
      </template>
      <!-- 聊天消息列表 -->
      <view
        v-for="(message, index) in messageList"
        :key="message.id || index"
        style="position: relative; padding: 10rpx 0"
      >
        <!-- 必须包裹一层view并设置transform: scaleY(-1)，否则会导致列表倒置 -->
        <view style="transform: scaleY(-1)">
          <!-- 用户消息 -->
          <view v-if="message.type === 'user'" class="message-wrapper user-message">
            <view
              class="message-content user-content"
              :class="{ 'history-message': message.isHistory }"
            >
              <text class="message-text" :selectable="true">{{ message.content }}</text>
              <view v-if="message.isHistory" class="history-tag">
                <text class="history-text">历史</text>
              </view>
            </view>
            <image 
              :src="userAvatarUrl || '/static/images/user/avatar-default.png'" 
              class="avatar user-avatar" 
              mode="aspectFill"
            />
          </view>

          <!-- AI介绍消息（默认消息） -->
          <view v-else-if="message.type === 'ai-intro'" class="ai-intro-container">
            <view class="ai-assistant">  
              <view class="assistant-header">
                <image src="/static/images/home/robot.png" class="robot-avatar" />
                <text class="assistant-name">AI小智</text>
              </view>

              <view class="assistant-message" @click="startChat">
                <text class="message-text">{{ message.content }}</text>
              </view>

              <view class="action-buttons">
                <view class="action-btn hot-signals" @click="showHotSignals">
                  <image src="/static/images/home/hot-icon.png" class="btn-icon" />
                  <text class="btn-text">热门资讯</text>
                </view>
                <view class="action-btn encrypted-signals" @click="showAltcoinsSelector">
                  <image src="/static/images/home/lock-icon.png" class="btn-icon" />
                  <text class="btn-text">热门山寨</text>
                </view>
              </view>
            </view>
          </view>

          <!-- AI消息 -->
          <view v-else class="message-wrapper ai-message">
            <image src="/static/images/home/robot.png" class="avatar ai-avatar" />
            <view
              class="message-content ai-content"
              :class="{ 'history-message': message.isHistory }"
            >
              <view class="ai-header">
                <text class="ai-name">AI小智</text>
                <text v-if="message.loading" class="typing-indicator">正在输入...</text>
                <view v-if="message.isHistory" class="history-tag">
                  <text class="history-text">历史</text>
                </view>
              </view>

              <!-- 显示消息内容 -->
              <text
                class="message-selectable-text"
                :selectable="true"
                :user-select="true"
                space="nbsp"
              >{{ formatMessage(message.content) }}</text>

              <!-- 加载中 -->
              <view v-if="message.loading" class="loading-dots">
                <view class="dot"></view>
                <view class="dot"></view>
                <view class="dot"></view>
              </view>
            </view>
          </view>
        </view>
      </view>

      <!-- 底部输入区域插槽 -->
      <template #bottom>
        <chat-input
          ref="chatInput"
          :disabled="isLoading"
          :show-coin-selector="showCoinSelector"
          :show-selector-header="false"
          :period-options="periodOptions"
          :is-vip="isVip"
          :remaining-count="remainingCount"
          @send="onSendMessage"
          @close-coin-selector="showCoinSelector = false"
          @select-period="sendPeriodAnalysis"
          @focus="onInputFocus"
          @blur="onInputBlur"
        ></chat-input>
      </template>
    </z-paging>

    <!-- SSE 流式请求处理组件 -->
    <view
      :start="sseStart"
      :change:start="sseRequests.sendStart"
    ></view>
  </view>
</template>

<script>
import { mapGetters } from 'vuex'
import { chatWithAiStream, getChatHistories, getChatSessions, getUserChatCount } from '@/api/ai'
import { getHotSzCurrencies } from '@/api/tactics'
import { parseAiAnalysis } from '@/utils/aiAnalysisFormatter'
import ChatInput from '@/components/chat-input/chat-input.vue'
import CustomPicker from '@/components/custom-picker/custom-picker.vue'
import { getToken } from '../../utils/auth'
import { API_BASE_URL, AI_EVENTSTREAM_URL } from '../../config'

export default {
  name: 'Home',
  components: {
    ChatInput,
    CustomPicker
  },
  computed: {
    ...mapGetters(['isVip', 'userVip']),
    ...mapGetters('user', ['userAvatarUrl']),
  },
  data() {
    return {
      messageList: [], // 消息列表
      isLoading: false, // 是否正在发送消息
      scrollHeight: '100vh', // 滚动区域高度
      currentLanguage: 'zh-CN', // 当前语言
      showCoinSelector: true, // 是否显示币种选择器 - 默认显示
      // 用户信息相关
      remainingCount: 0, // 剩余使用次数
      showNoCountModal: false, // 是否显示次数用完弹窗
      isFirstLoad: true, // 是否是首次加载，用于避免刷新时重复调用接口
      // 历史会话相关
      sessionList: [], // 历史会话列表
      todaySessions: [], // 今天的会话
      yesterdaySessions: [], // 昨天的会话
      recentSessions: [], // 前七天的会话
      currentSessionId: '', // 当前会话ID
      // 热门山寨币列表
      hotAltcoins: [], // 热门山寨币列表
      isLoadingAltcoins: false, // 是否正在加载热门山寨币
      altcoinsColumns: [], // picker 列数据
      selectedAltcoinIndex: 0, // 选中的山寨币索引
      // 周期选项
      periodOptions: [
        { key: '1h_btc', label: '1小时BTC', query: '请分析1小时BTC走势' },
        { key: '1h_eth', label: '1小时ETH', query: '请分析1小时ETH走势' },
        { key: '4h_btc', label: '4小时BTC', query: '请分析4小时BTC走势' },
        { key: '4h_eth', label: '4小时ETH', query: '请分析4小时ETH走势' },
        { key: '8h_btc', label: '8小时BTC', query: '请分析8小时BTC走势' },
      ],
      defaultMessageList: [
        // 默认AI介绍消息，始终存在
        {
          id: 'default-ai-intro',
          type: 'ai-intro',
          content: '我是Crypto智能交易助理，提供专业的分析与策略建议！',
          timestamp: new Date(),
          isDefault: true,
        },
      ],
      // SSE 流式请求相关
      sseStart: null, // SSE 请求启动参数
      currentAiMessageId: null, // 当前正在接收的 AI 消息ID
      currentIosXhr: null, // iOS 环境中的 plus.net.XMLHttpRequest 对象
      // 首次进入弹窗
      WELCOME_MODAL_SHOWN_KEY: 'app_welcome_modal_shown', // 本地存储键名
    }
  },
  onLoad() {
    console.log('首页加载')
    // 获取用户头像
    // this.loadUserAvatar()
    // 非会员用户需要获取剩余次数
    if (!this.isVip && getToken()) {
      this.loadChatCount()
    }
    // 检查是否需要显示首次进入提醒弹窗
    this.checkAndShowWelcomeModal()
  },
  onUnload() {
    // 页面卸载时清理 iOS 的 XMLHttpRequest
    if (this.currentIosXhr) {
      console.log('页面卸载，终止 iOS XHR 请求')
      this.currentIosXhr.abort()
      this.currentIosXhr = null
    }
  },
  onShow() {
    console.log('首页显示，刷新 z-paging 布局')

    // 如果是首次加载（onLoad刚执行完），onShow也会立即触发
    if (this.isFirstLoad) {
      this.isFirstLoad = false
      // 首次显示时，只需要刷新布局
      this.$nextTick(() => {
        if (this.$refs.paging) {
          setTimeout(() => {
            this.$refs.paging.updateFixedLayout()
            console.log('z-paging 布局已刷新')
          }, 100)
        }
      })
      return
    }

    // 非会员用户需要获取剩余次数
    if (!this.isVip && getToken()) {
      this.loadChatCount()
    }

    // 确保 z-paging 正确计算高度，解决 iOS 滚动锁定问题
    this.$nextTick(() => {
      if (this.$refs.paging) {
        // 延迟执行，确保页面完全渲染
        setTimeout(() => {
          this.$refs.paging.updateFixedLayout()
          console.log('z-paging 布局已刷新')
        }, 100)
      }
    })
  },
  methods: {
    /**
     * 检查并显示首次进入提醒弹窗
     */
    checkAndShowWelcomeModal() {
      // 检查本地存储，判断是否已显示过
      const hasShown = uni.getStorageSync(this.WELCOME_MODAL_SHOWN_KEY)
      if (!hasShown) {
        // 延迟显示，确保页面渲染完成
        this.$nextTick(() => {
          setTimeout(() => {
            if (this.$refs.welcomeModal) {
              this.$refs.welcomeModal.open()
            }
          }, 500)
        })
      }
    },

    /**
     * 首次进入弹窗确认回调
     */
    handleWelcomeConfirm() {
      // 标记已显示过，存储到本地
      uni.setStorageSync(this.WELCOME_MODAL_SHOWN_KEY, true)
    },

    // 格式化消息内容
    formatMessage(content) {
      // 使用 utils/aiAnalysisFormatter.js 的 parseAiAnalysis 函数
      return parseAiAnalysis(content)
    },

    /**
     * iOS 专用：使用 plus.net.XMLHttpRequest 处理 SSE 流式请求
     * 为什么要单独处理 iOS？
     * - iOS WKWebView 限制了 renderjs 中的网络请求
     * - plus.net.XMLHttpRequest 可以绕过这个限制
     * - 支持 onreadystatechange 事件实时读取流式数据
     */
    handleIosSseRequest(options) {
      // #ifdef APP-PLUS
      console.log('handleIosSseRequest 被调用:', options)

      // 如果有正在进行的 iOS 请求，先终止
      if (this.currentIosXhr) {
        this.currentIosXhr.abort()
        this.currentIosXhr = null
      }

      try {
        // 创建 plus.net.XMLHttpRequest 对象
        const xhr = new plus.net.XMLHttpRequest()
        this.currentIosXhr = xhr

        // 用于追踪已处理的数据位置
        let lastProcessedIndex = 0

        // 配置请求
        xhr.open(options.method, options.url, true)

        // 设置超时时间
        xhr.timeout = 30000

        // 设置请求头
        if (options.headers) {
          Object.keys(options.headers).forEach(key => {
            xhr.setRequestHeader(key, options.headers[key])
          })
        }

        // 监听状态变化 - 这是流式读取的关键！
        xhr.onreadystatechange = () => {
          console.log('iOS XHR readyState:', xhr.readyState, 'status:', xhr.status)

          // readyState:
          // 0 = UNSENT (未初始化)
          // 1 = OPENED (已打开)
          // 2 = HEADERS_RECEIVED (已收到响应头)
          // 3 = LOADING (正在接收数据) ← 流式读取的关键状态
          // 4 = DONE (请求完成)

          // 在 readyState = 3 时就可以开始读取部分响应数据
          if (xhr.readyState === 3 || xhr.readyState === 4) {
            try {
              const responseText = xhr.responseText || ''

              // 只处理新接收的数据（避免重复处理）
              const newText = responseText.substring(lastProcessedIndex)
              lastProcessedIndex = responseText.length

              if (newText) {
                console.log('iOS 收到新数据，长度:', newText.length, '内容预览:', newText.substring(0, 50))
                // 解析并处理 SSE 数据
                this.parseIosSseData(newText)
              }

              // 请求完成
              if (xhr.readyState === 4) {
                console.log('iOS 请求完成，status:', xhr.status)
                if (xhr.status >= 200 && xhr.status < 300) {
                  this.onSseFinish()
                } else {
                  this.onSseError(`HTTP error! status: ${xhr.status}`)
                }
                this.currentIosXhr = null
              }
            } catch (error) {
              console.error('iOS 处理流数据失败:', error)
            }
          }
        }

        // 请求错误
        xhr.onerror = (event) => {
          console.error('iOS XHR 错误:', event)
          this.onSseError('iOS 网络请求失败')
          this.currentIosXhr = null
        }

        // 请求超时
        xhr.ontimeout = () => {
          console.error('iOS XHR 超时')
          this.onSseError('iOS 请求超时')
          this.currentIosXhr = null
        }

        // 发送请求
        const requestBody = options.data ? JSON.stringify(options.data) : null
        console.log('iOS 发送 SSE 请求')
        xhr.send(requestBody)

      } catch (error) {
        console.error('iOS 创建 XHR 失败:', error)
        this.onSseError(error.message || 'iOS 请求创建失败')
      }
      // #endif

      // #ifndef APP-PLUS
      console.warn('handleIosSseRequest 只能在 App 环境中使用')
      this.onSseError('不在 App 环境中')
      // #endif
    },

    /**
     * 解析 iOS SSE 数据
     */
    parseIosSseData(text) {
      if (!text) return

      // 按行分割数据
      const lines = text.split('\n')

      for (const line of lines) {
        const trimmedLine = line.trim()
        if (!trimmedLine) continue

        // 解析 SSE 格式：data: content
        if (trimmedLine.startsWith('data:')) {
          const content = trimmedLine.substring(5).trim()

          // 跳过 [DONE] 标记
          if (content === '[DONE]') {
            console.log('iOS 收到结束标记 [DONE]')
            this.onSseFinish()
            // 终止请求
            if (this.currentIosXhr) {
              this.currentIosXhr.abort()
              this.currentIosXhr = null
            }
            break
          }

          // 发送数据到消息处理函数
          if (content) {
            this.onSseMessage(content)
          }
        }
      }
    },

    // 获取AI聊天次数（仅非会员需要）
    async loadChatCount() {
      try {
        const chatCountResponse = await getUserChatCount()
        if (chatCountResponse.code === 200 && chatCountResponse.data !== undefined) {
          this.remainingCount = chatCountResponse.data || 0
        }
      } catch (error) {
        console.error('获取聊天次数失败:', error)
      }
    },

    // 创建新会话
    createNewSession() {
      console.log('创建新会话')

      // 清空当前会话ID 
      this.currentSessionId = ''

      // 重新加载数据（只显示默认消息）
      if (this.$refs.paging) {
        this.$refs.paging.reload()
      }

      uni.showToast({
        title: '已创建新会话',
        icon: 'none',
        duration: 1500
      })
    },
    // z-paging 查询方法
    async queryList(pageNo, pageSize) {
      try {
        // 如果没有 token，只显示默认消息
        if (!getToken()) {
          if (pageNo === 1) {
            this.$refs.paging.complete([...this.defaultMessageList])
          } else {
            this.$refs.paging.complete([])
          }
          return
        }

        // 如果没有选择会话，只显示默认消息
        if (!this.currentSessionId) {
          if (pageNo === 1) {
            this.$refs.paging.complete([...this.defaultMessageList])
          } else {
            this.$refs.paging.complete([])
          }
          return
        }

        // 获取指定会话的历史聊天记录
        const response = await getChatHistories(pageNo, pageSize, this.currentSessionId)

        if (response.code === 200 && response.data) {
          const { records = [], total = 0, current = 1, pages = 0 } = response.data

          // 转换历史记录格式
          const historyMessages = []

          // 按ID分组聊天记录
          const chatGroups = {}
          records.forEach(record => {
            if (!chatGroups[record.id]) {
              chatGroups[record.id] = []
            }
            chatGroups[record.id].push(record)
          })

          // 处理每个聊天组
          Object.keys(chatGroups).forEach(chatId => {
            const group = chatGroups[chatId]

            // 按聊天类型排序，确保USER在前，ANSWERER在后
            group.sort((a, b) => {
              if (a.chatType === 'USER' && b.chatType === 'ANSWERER') return -1
              if (a.chatType === 'ANSWERER' && b.chatType === 'USER') return 1
              return 0
            })

            group.forEach(record => {
              // 处理时间格式：[年,月,日,时,分,秒] -> Date对象
              let timestamp = new Date()
              if (record.date && Array.isArray(record.date) && record.date.length >= 6) {
                const [year, month, day, hour, minute, second] = record.date
                timestamp = new Date(year, month - 1, day, hour, minute, second)
              }

              if (record.chatType === 'USER') {
                // 用户消息 - 去掉换行符
                let userContent = record.content || ''
                userContent = userContent.replace(/^\n+|\n+$/g, '').trim()

                historyMessages.push({
                  id: `user-${record.id}-${pageNo}`,
                  type: 'user',
                  content: userContent,
                  timestamp: timestamp,
                  isHistory: true,
                })
              } else if (record.chatType === 'ANSWERER') {
                // AI回答 - 需要解析JSON内容
                let aiContent = record.content || ''

                try {
                  // 尝试解析JSON格式的content
                  const parsedContent = JSON.parse(record.content)
                  if (parsedContent.content) {
                    aiContent = parsedContent.content
                  }
                } catch (e) {
                  // 如果不是JSON格式，直接使用原内容
                  aiContent = record.content || '回答内容解析失败'
                }

                // 去掉开头和结尾的换行符
                aiContent = aiContent.replace(/^\n+|\n+$/g, '').trim()

                // 创建消息对象
                const aiMessage = {
                  id: `ai-${record.id}-${pageNo}`,
                  type: 'ai',
                  content: aiContent,
                  timestamp: timestamp,
                  isHistory: true,
                }

                // Markdown 格式化已由 ua2-markdown 组件自动处理，无需手动格式化

                historyMessages.push(aiMessage)
              }
            })
          })

          // // 按时间降序排序（最新的在前面），配合z-paging的倒序显示后，最旧消息在上，最新消息在下
          // historyMessages.sort((a, b) => b.timestamp - a.timestamp)
          historyMessages.reverse()
          // 如果是第一页，需要合并默认消息
          if (pageNo === 1) {
            const allMessages = [...this.defaultMessageList,...historyMessages]
            this.$refs.paging.complete(allMessages)
          } else {
            // 后续页面只返回历史记录
            this.$refs.paging.complete(historyMessages)
          }
        } else {
          // 如果获取失败
          if (pageNo === 1) {
            // 第一页失败时显示默认消息
            this.$refs.paging.complete([...this.defaultMessageList])
          } else {
            // 其他页失败时返回空数组
            this.$refs.paging.complete([])
          }

          // 显示错误提示
          if (response && response.message) {
            uni.showToast({
              title: response.message,
              icon: 'none',
              duration: 2000,
            })
          }
        }
      } catch (error) {
        console.error('加载聊天历史失败:', error)

        // 错误时的处理
        if (pageNo === 1) {
          // 第一页错误时显示默认消息
          this.$refs.paging.complete([...this.defaultMessageList])
        } else {
          // 其他页错误时返回空数组，并停止加载更多
          this.$refs.paging.complete([])
        }

        // 显示网络错误提示
        uni.showToast({
          title: '网络连接失败，请稍后重试',
          icon: 'none',
          duration: 2000,
        })
      }
    },

    // 监听键盘高度改变
    keyboardHeightChange(res) {
      console.log('键盘高度变化:', res)
      // 通知子组件键盘高度改变
      if (this.$refs.chatInput) {
        this.$refs.chatInput.updateKeyboardHeightChange(res)
      }
    },

    // 用户尝试隐藏键盘
    hidedKeyboard() {
      console.log('隐藏键盘')
      // 通知子组件隐藏键盘
      if (this.$refs.chatInput) {
        this.$refs.chatInput.hidedKeyboard()
      }
    },

    // 输入框聚焦
    onInputFocus(e) {
      console.log('输入框聚焦')
      // z-paging 会自动滚动到底部
      this.$nextTick(() => {
        if (this.$refs.paging) {
          this.$refs.paging.scrollToBottom()
        }
      })
    },

    // 输入框失焦
    onInputBlur(e) {
      console.log('输入框失焦')
    },

    // 处理发送消息
    async onSendMessage(message) {
      if (!message || this.isLoading) return

      // 检查是否登录
      const token = getToken()
      if (!token) {
        uni.showToast({
          title: '请先登录',
          icon: 'none'
        })
        setTimeout(() => {
          uni.navigateTo({
            url: '/subPages/auth/login'
          })
        }, 1500)
        return
      }

      // 检查非会员用户的使用次数
      if (!this.isVip && this.remainingCount <= 0) {
        this.$refs.noCountModal.open()
        return
      }

      this.isLoading = true

      // 添加用户消息到聊天记录
      this.$refs.paging.addChatRecordData({
        id: Date.now(),
        type: 'user',
        content: message,
        timestamp: new Date(),
      })

      // 添加AI加载消息
      // 创建 AI 消息占位符（用于流式更新）
      const aiMessageId = Date.now() + 1
      this.currentAiMessageId = aiMessageId
      this.$refs.paging.addChatRecordData({
        id: aiMessageId,
        type: 'ai',
        content: '',
        loading: true,
        timestamp: new Date(),
      })

      // 获取 token
      // const token = getToken() || ''

      // 触发 SSE 流式请求（使用代理路径，不要用完整 URL）
      this.sseStart = {
        url: `${AI_EVENTSTREAM_URL}/chat/chatWithAiV2`,
        method: 'POST',
		headers: {
		  'Accept': 'text/event-stream',
		  'Content-Type': 'application/json',
		  'Authorization': token ? `Bearer ${token}` : '',
		  'source-client': 'miniapp',
		},
        data: {
          question: message,
        }
      }
    },

    // SSE 消息回调 - 接收流式数据
    onSseMessage(msg) {
      if (!this.currentAiMessageId) return

      try {
        // 解析 JSON 格式的消息（如果需要）
        let content = msg
        try {
          const parsed = JSON.parse(msg)
          if (parsed.content) {
            content = parsed.content
          }
        } catch (e) {
          // 不是 JSON 格式，直接使用原始内容
        }

        // 获取当前 AI 消息
        const message = this.messageList.find(m => m.id === this.currentAiMessageId)
        if (message) {
          // 追加新内容
          message.content += content
          this.$forceUpdate()

          // 滚动到底部
          this.$nextTick(() => {
            this.scrollToBottom()
          })
        }
      } catch (error) {
        console.error('处理 SSE 消息失败:', error)
      }
    },

    // SSE 请求完成回调
    onSseFinish() {
      console.log('SSE 请求完成')

      if (this.currentAiMessageId) {
        // 移除 loading 状态
        const message = this.messageList.find(m => m.id === this.currentAiMessageId)
        if (message) {
          message.loading = false
          // 如果内容为空，显示默认错误消息
          if (!message.content || message.content.trim() === '') {
            message.content = '抱歉，我现在无法回答您的问题，请稍后再试。'
          }
          this.$forceUpdate()
        }

        this.currentAiMessageId = null
      }

      this.isLoading = false

      // 非会员用户减少剩余次数
      if (!this.isVip && this.remainingCount > 0) {
        this.remainingCount--
        console.log('剩余次数:', this.remainingCount)
      }

      // 滚动到底部
      this.scrollToBottom()
    },

    // SSE 错误回调
    onSseError(err) {
      console.error('SSE 请求错误:', err)

      if (this.currentAiMessageId) {
        this.removeMessageById(this.currentAiMessageId)
        this.$refs.paging.addChatRecordData({
          id: Date.now() + 2,
          type: 'ai',
          content: '发送消息失败，请检查网络连接',
          loading: false,
          timestamp: new Date(),
        })

        this.currentAiMessageId = null
      }

      this.isLoading = false
    },
    // 开始聊天
    startChat() {
      // 聊天记录模式下不需要显示/隐藏聊天区域
      // 直接滚动到底部即可
      this.scrollToBottom()
    },


    // 根据ID移除消息
    removeMessageById(id) {
      const index = this.messageList.findIndex(msg => msg.id === id)
      if (index !== -1) {
        this.messageList.splice(index, 1)
      }
    },

    /**
     * 更新消息内容（用于流式数据更新）
     * @param {Number} messageId - 消息ID
     * @param {String} content - 消息内容
     * @param {Boolean} loading - 是否显示 loading 状态
     */
    updateMessageContent(messageId, content, loading = false) {
      const message = this.messageList.find(msg => msg.id === messageId)
      if (message) {
        message.content = content
        message.loading = loading

        // 如果消息加载完成，尝试格式化为 Markdown
        if (!loading && content) {
          // Markdown 格式化已由 ua2-markdown 组件自动处理，无需手动格式化
        }

        // 触发视图更新
        this.$forceUpdate()

        // 滚动到底部（可选）
        this.$nextTick(() => {
          this.scrollToBottom()
        })
      }
    },

    // 发送快捷问题
    sendQuickQuestion(question) {
      this.onSendMessage(question)
    },

    // 处理错误
    handleError(errorMessage) {
      // 移除加载消息
      const loadingIndex = this.messageList.findIndex(msg => msg.loading)
      if (loadingIndex !== -1) {
        this.messageList.splice(loadingIndex, 1)
      }

      // 添加错误消息
      const errorMsg = {
        id: Date.now() + 3,
        type: 'ai',
        content: errorMessage,
        loading: false,
        timestamp: new Date(),
      }
      this.messageList.push(errorMsg)

      // 显示提示
      uni.showToast({
        title: errorMessage,
        icon: 'none',
        duration: 2000,
      })
    },

    // 滚动到底部
    scrollToBottom() {
      this.$nextTick(() => {
        if (this.$refs.paging) {
          // 使用z-paging的方法滚动到底部
          this.$refs.paging.scrollToBottom()
        }
      })
    },

    // 显示历史会话列表
    async showChatHistory() {
      // 打开 popup
      this.$refs.sessionPopup.open()
      // 加载历史会话列表
      await this.loadSessionList()
    },
    
    // popup 状态变化回调
    onPopupChange(e) {
      console.log('Popup 状态变化:', e)
    },

    // 加载历史会话列表
    async loadSessionList() {
      try {
        const response = await getChatSessions(1, 50) // 获取前50条会话

        if (response.code === 200 && response.data) {
          const { records = [] } = response.data

          // 按时间分组会话
          this.groupSessionsByTime(records)
        } else {
          uni.showToast({
            title: response.message || '获取会话列表失败',
            icon: 'none',
          })
        }
      } catch (error) {
        console.error('加载会话列表失败:', error)
        uni.showToast({
          title: '网络连接失败',
          icon: 'none',
        })
      } finally {
        uni.hideLoading()
      }
    },

    // 按时间分组会话
    groupSessionsByTime(sessions) {
      const now = new Date()
      const today = new Date(now.getFullYear(), now.getMonth(), now.getDate())
      const yesterday = new Date(today.getTime() - 24 * 60 * 60 * 1000)
      const sevenDaysAgo = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000)

      this.todaySessions = []
      this.yesterdaySessions = []
      this.recentSessions = []

      sessions.forEach(session => {
        // 解析创建时间
        let createTime = new Date()
        if (session.createTime) {
          createTime = new Date(session.createTime)
        }

        // 根据时间分组
        if (createTime >= today) {
          this.todaySessions.push(session)
        } else if (createTime >= yesterday) {
          this.yesterdaySessions.push(session)
        } else if (createTime >= sevenDaysAgo) {
          this.recentSessions.push(session)
        }
      })
    },

    // 跳转到客服页面
    goToCustomerService() {
      this.$refs.noCountModal.close()
      uni.switchTab({
        url: '/pages/my/my'
      })
    },

    // 关闭次数用完弹窗
    closeNoCountModal() {
      this.$refs.noCountModal.close()
    },

    // 打开指定会话
    async openSession(sessionId, title) {
      // 设置当前会话ID
      this.currentSessionId = sessionId
      // 关闭 popup
      this.$refs.sessionPopup.close()

      // 清空当前消息列表，重新加载该会话的历史记录
      try {
        // 重新加载该会话的聊天记录
        this.$refs.paging.reload()

        uni.hideLoading()
        uni.showToast({
          title: `已切换到: ${title || '会话'}`,
          icon: 'none',
        })
      } catch (error) {
        console.error('加载会话失败:', error)
        uni.hideLoading()
        uni.showToast({
          title: '加载会话失败',
          icon: 'none',
        })
      }
    },

    // 删除会话
    async deleteSession(sessionId) {
      uni.showModal({
        title: '确认删除',
        content: '确定要删除这个会话吗？',
        success: async res => {
          if (res.confirm) {
            // TODO: 调用删除会话的API
            // await delChat({ sessionId })
            // 重新加载会话列表
            await this.loadSessionList()
            uni.showToast({
              title: '删除成功',
              icon: 'none',
            })
          }
        },
      })
    },

    // 关闭会话侧边栏
    closeSessionDrawer() {
      this.$refs.sessionPopup.close()
    },

    // 格式化时间
    formatTime(timeStr) {
      if (!timeStr) return ''
      
      const time = new Date(timeStr)
      const now = new Date()
      const diff = now - time

      // 小于1分钟
      if (diff < 60000) {
        return '刚刚'
      }
      // 小于1小时
      if (diff < 3600000) {
        return Math.floor(diff / 60000) + '分钟前'
      }
      // 小于1天
      if (diff < 86400000) {
        return Math.floor(diff / 3600000) + '小时前'
      }
      // 显示具体时间
      const month = time.getMonth() + 1
      const day = time.getDate()
      const hour = time.getHours().toString().padStart(2, '0')
      const minute = time.getMinutes().toString().padStart(2, '0')
      return `${month}月${day}日 ${hour}:${minute}`
    },

    // 刷新聊天历史记录
    refreshChatHistory() {
      if (this.$refs.paging) {
        this.$refs.paging.reload()
        uni.showToast({
          title: '正在刷新历史记录...',
          icon: 'loading',
          duration: 1500,
        })
      }
    },

    // 清空聊天历史
    clearChatHistory() {
      // 重置为只包含默认消息
      this.currentSessionId = ''
      if (this.$refs.paging) {
        this.$refs.paging.complete([...this.defaultMessageList])
      }
      uni.showToast({
        title: '历史记录已清空',
        icon: 'none',
      })
    },

    // 显示语言选择器 - 跳转到语言设置页面
    showLanguageSelector() {
      uni.navigateTo({
        url: '/subPages/settings/language-setting'
      })
    },

    // 切换语言
    switchLanguage(language) {
      this.currentLanguage = language.key

      // 更新快捷问题的语言
      this.updateQuestionsByLanguage(language.key)

      uni.showToast({
        title: `已切换到${language.label}`,
        icon: 'none',
      })
  
      // 这里可以调用多语言API或本地化逻辑
      // TODO: 实现实际的语言切换逻辑
    },

    // 根据语言更新快捷问题
    updateQuestionsByLanguage(langKey) {
      const questions = {
        'zh-CN': ['今日市场行情如何？', '推荐一些交易策略', '比特币走势分析', '风险管理建议'],
        en: [
          'How is the market today?',
          'Recommend some trading strategies',
          'Bitcoin trend analysis',
          'Risk management advice',
        ],
        tr: [
          'Bugün piyasa nasıl?',
          'Bazı ticaret stratejileri öner',
          'Bitcoin trend analizi',
          'Risk yönetimi tavsiyeleri',
        ],
      }

      this.quickQuestions = questions[langKey] || questions['zh-CN']
    },

    // 显示热门资讯 - 跳转到快讯页面
    showHotSignals() {
      uni.switchTab({
        url: '/pages/data/index'
      })
    },

    // 显示热门山寨币种选择
    async showAltcoinsSelector() {
      // 如果还没有加载热门山寨币，先加载
      if (this.hotAltcoins.length === 0 && !this.isLoadingAltcoins) {
        await this.loadHotAltcoins()
      }

      // 如果加载失败或没有数据，提示用户
      if (this.hotAltcoins.length === 0) {
        uni.showToast({
          title: '暂无热门山寨币数据',
          icon: 'none',
          duration: 2000
        })
        return
      }

      // 隐藏 tabbar
      uni.hideTabBar()

      // 打开 picker
      this.$refs.altcoinsPicker.open()
    },

    /**
     * 取消选择热门山寨币
     */
    onAltcoinCancel() {
      console.log('取消选择币种')

      // 显示 tabbar
      uni.showTabBar()
    },

    /**
     * 确认选择热门山寨币
     */
    onAltcoinConfirm(e) {
      console.log('选择的币种:', e)

      // 显示 tabbar
      uni.showTabBar()

      if (e && e.value && e.value.length > 0) {
        const selectedCoin = e.value[0]

        // 更新选中索引
        this.selectedAltcoinIndex = e.index[0]

        // 发送分析消息
        const query = `请分析4小时${selectedCoin.text}的走势`
        this.onSendMessage(query)

        // uni.showToast({
        //   title: `正在分析${selectedCoin.text}`,
        //   icon: 'loading',
        //   duration: 1500
        // })
      }
    },

    /**
     * 加载热门山寨币列表
     */
    async loadHotAltcoins() {
      if (this.isLoadingAltcoins) return

      try {
        this.isLoadingAltcoins = true

        const response = await getHotSzCurrencies({
          pageSize: 1000,
          pageNo: 1
        })

        console.log('热门山寨币响应:', response)

        if (response.code === 200 && response.data) {
          // 处理分页数据
          if (response.data.records && Array.isArray(response.data.records)) {
            this.hotAltcoins = response.data.records
          }
          // 处理直接数组数据
          else if (Array.isArray(response.data)) {
            this.hotAltcoins = response.data
          }

          // 构建 picker 列数据（自定义 picker 不需要二维数组）
          this.altcoinsColumns = this.hotAltcoins.map(coin => ({
            text: coin.currencyCode,
            value: coin.id || coin.currencyCode,
            currencyName: coin.currencyName
          }))

          console.log('热门山寨币列表:', this.hotAltcoins)
          console.log('Picker 列数据:', this.altcoinsColumns)
        } else {
          console.error('获取热门山寨币失败:', response.message)
          uni.showToast({
            title: response.message || '获取热门山寨币失败',
            icon: 'none',
            duration: 2000
          })
        }
      } catch (error) {
        console.error('加载热门山寨币失败:', error)
        uni.showToast({
          title: '网络连接失败',
          icon: 'none',
          duration: 2000
        })
      } finally {
        this.isLoadingAltcoins = false
      }
    },

    // 发送周期分析
    sendPeriodAnalysis(period) {
      // 直接发送消息
      this.onSendMessage(period.query)

      // 发送后隐藏币种选择器
      this.showCoinSelector = false

    //   uni.showToast({
    //     title: `正在分析${period.label}`,
    //     icon: 'loading',
    //     duration: 1500,
    //   })
    },

    /**
     * 渲染 Markdown 为 HTML
     * @param {string} content - Markdown 内容
     * @returns {string} HTML 内容
     */
    renderMarkdown(content) {
      if (!content) return ''
      // 先整理 AI 输出的格式
      const formattedContent = formatTradingAnalysis(content)
      // 再转换为 HTML（用于 uv-parse）
      return this.markdownToHtmlForParse(formattedContent)
    },

    /**
     * 将 Markdown 转换为 uv-parse 支持的 HTML（手机端适配版本）
     * @param {string} markdown - Markdown 内容
     * @returns {string} HTML 内容
     */
    markdownToHtmlForParse(markdown) {
      if (!markdown) return ''

      let html = markdown

      // 转义 HTML 特殊字符
      const escapeHtml = (text) => {
        if (!text) return ''
        const map = {
          '&': '&amp;',
          '<': '&lt;',
          '>': '&gt;',
          '"': '&quot;',
          "'": '&#039;'
        }
        return text.replace(/[&<>"']/g, m => map[m])
      }

      html = escapeHtml(html)

      // 标题处理 - 使用更小的字体，适合手机端
      // 标题字体：28rpx（比正文稍大一点点）
      html = html.replace(/(?:^|\n)###\s+(.+?)(?=\n|$)/gm, '\n<div style="font-size: 28rpx; font-weight: 600; margin: 10rpx 0 6rpx 0; color: #1a1a1a;"><strong>$1</strong></div>')
      html = html.replace(/(?:^|\n)##\s+(.+?)(?=\n|$)/gm, '\n<div style="font-size: 28rpx; font-weight: 600; margin: 10rpx 0 6rpx 0; color: #1a1a1a;"><strong>$1</strong></div>')
      html = html.replace(/(?:^|\n)#\s+(.+?)(?=\n|$)/gm, '\n<div style="font-size: 28rpx; font-weight: 600; margin: 10rpx 0 6rpx 0; color: #1a1a1a;"><strong>$1</strong></div>')

      // 粗体处理
      html = html.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')

      // 列表处理 - 使用更小的字体和间距
      // 列表字体：26rpx，行高 1.5
      html = html.replace(/(?:^|\n)-\s+(.+?)(?=\n|$)/gm, '\n<div style="margin-left: 12rpx; margin-top: 4rpx; line-height: 1.5; color: #333; font-size: 26rpx;">• $1</div>')

      // 引用处理 - 使用更小的字体
      html = html.replace(/(?:^|\n)&gt;\s*(.+?)(?=\n|$)/gm, '\n<div style="border-left: 3rpx solid #06CBB6; padding-left: 10rpx; margin: 10rpx 0; color: #666; font-style: italic; font-size: 24rpx; line-height: 1.5;">$1</div>')

      // 段落处理 - 双换行表示新段落
      html = html.replace(/\n\n/g, '</p><p>')

      // 单换行处理 - 保留为换行
      html = html.replace(/\n/g, '<br/>')

      // 包裹段落 - 使用更小的字体
      if (!html.startsWith('<')) {
        html = `<p style="margin: 0 0 12rpx 0; line-height: 1.5; color: #333; font-size: 26rpx;">${html}</p>`
      }

      return html
    },
  },
}
</script>

<script module="sseRequests" lang="renderjs">
// AbortController Polyfill for older environments
if (typeof AbortController === 'undefined') {
  window.AbortController = class AbortController {
    constructor() {
      this.signal = {
        aborted: false,
        addEventListener: () => {},
        removeEventListener: () => {}
      }
    }
    abort() {
      this.signal.aborted = true
    }
  }
}

/**
 * StreamFetcher - 流式请求处理类
 * 基于 yao-SseChat 的实现
 */
class StreamFetcher {
  constructor(options) {
    this.options = {
      method: 'GET',
      headers: {},
      timeout: 30000,
      ...options
    }
    this.controller = new AbortController()
    this.reader = null
    this.isAborted = false
    this.totalBytes = 0
    this.receivedBytes = 0
  }

  async fetch() {
    const {
      url,
      method,
      headers,
      body,
      timeout,
      onMessage,
      onFinish,
      onError,
      onProgress
    } = this.options

    // 超时处理
    const timeoutId = setTimeout(() => {
      this.abort(new Error(`Request timed out after ${timeout}ms`))
    }, timeout)

    try {

      const response = await fetch(url, {
        method,
        headers,
        body: body ? JSON.stringify(body) : null,
        signal: this.controller.signal
      })

      // 检查响应是否成功
      if (!response.ok) {
        // 读取错误响应内容
        const errorText = await response.text()
        console.log('错误响应内容:', errorText)
        throw new Error(`HTTP error! status: ${response.status}, body: ${errorText}`)
      }

      // 获取内容长度(如果可用)
      const contentLength = response.headers.get('content-length')
      this.totalBytes = contentLength ? parseInt(contentLength) : 0

      // 获取reader
      this.reader = response.body.getReader()
      const textDecoder = new TextDecoder()

      // SSE 格式处理：处理 data: 开头的行
      let buffer = '' // 缓存未完整的行

      // 处理流数据
      while (true) {
        if (this.isAborted) break

        const { done, value } = await this.reader.read()

        if (done) {
          if (onFinish) onFinish()
          break
        }

        // 更新接收字节数
        this.receivedBytes += value.byteLength
        if (onProgress && this.totalBytes > 0) {
          onProgress({
            received: this.receivedBytes,
            total: this.totalBytes,
            percent: (this.receivedBytes / this.totalBytes * 100).toFixed(2)
          })
        }

        // 处理数据
        const str = textDecoder.decode(value, { stream: true })

        // 将新数据添加到缓冲区
        buffer += str

        // 按 \n\n 分割 SSE 事件
        const events = buffer.split('\n\n')

        // 最后一个可能是不完整的，保留在缓冲区
        buffer = events.pop() || ''

        // 处理完整的事件
        for (const event of events) {
          if (this.isAborted) break

          // 解析 SSE 格式：data: content
          const lines = event.split('\n').filter(line => line.trim() !== '')

          for (const line of lines) {
            if (line.startsWith('data:')) {
              const content = line.substring(5).trim()

              // 跳过 [DONE] 标记
              if (content === '[DONE]') {
                if (onFinish) onFinish()
                this.isAborted = true
                break
              }

              if (content && onMessage) {
                onMessage(content)
              }
            }
          }
        }
      }
    } catch (error) {
      if (!this.isAborted && onError) {
        onError(error)
      }
    } finally {
      clearTimeout(timeoutId)
      if (this.reader) {
        this.reader.releaseLock()
      }
    }
  }

  abort(reason) {
    if (!this.isAborted) {
      this.isAborted = true
      this.controller.abort(reason || 'Request aborted by user')
    }
  }
}

export default {
  data() {
    return {
      currentFetcher: null
    }
  },
  methods: {
    sendStart(newValue, oldValue, ownerInstance, instance) {
      if (newValue == null) return

      // 如果有正在进行的请求，先终止
      if (this.currentFetcher) {
        this.currentFetcher.abort()
      }

      // 检测是否为 iOS 环境
      const userAgent = navigator.userAgent.toLowerCase()
      const isIOS = /iphone|ipad|ipod/.test(userAgent)
      const isApp = typeof window.plus !== 'undefined'

      console.log('SSE 请求环境检测:', {
        userAgent: navigator.userAgent,
        isIOS,
        isApp,
        platform: isApp ? 'App' : 'Web'
      })

      // 如果是 iOS App 环境，使用 plus.net.XMLHttpRequest
      // 原因：iOS WKWebView 限制了 renderjs 中 fetch 的网络请求
      if (isIOS && isApp) {
        console.log('检测到 iOS App，使用 plus.net.XMLHttpRequest 处理流式请求')
        ownerInstance.callMethod('handleIosSseRequest', {
          url: newValue.url,
          method: newValue.method,
          headers: newValue.headers,
          data: newValue.data
        })
        return
      }

      // Android App 或 Web 环境，使用原有的 fetch 方案
      console.log('使用标准 fetch 方案 (Android/Web)')
      this.currentFetcher = new StreamFetcher({
        url: newValue.url,
        method: newValue.method,
        headers: newValue.headers,
        body: newValue.data,
        onMessage: (data) => {
          // 调用 uni-app 方法
          ownerInstance.callMethod('onSseMessage', data)
        },
        onFinish: () => {
          ownerInstance.callMethod('onSseFinish')
          this.currentFetcher = null
        },
        onError: (error) => {
          ownerInstance.callMethod('onSseError', error.message)
          this.currentFetcher = null
        },
        onProgress: ({ received, total, percent }) => {
          // 可选：处理进度
          console.log(`Progress: ${percent}%`)
        }
      })

      // 开始请求
      this.currentFetcher.fetch()
    }
  },
  mounted() {
    console.log('SSE renderjs 模块已挂载')
  }
}
</script>

<style lang="scss">
// uv-ui popup 容器样式
.drawer-container {
  display: flex;
  flex-direction: column;
  width: 560rpx;
  height: 100vh;
  background: linear-gradient(180deg, #f8f9fa 0%, #ffffff 100%);

  .drawer-header {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 24rpx 20rpx;
    padding-top: calc(var(--status-bar-height) + 20rpx);
    background: #fff;
    border-bottom: 2rpx solid #f0f0f0;

    .drawer-title {
      font-size: 32rpx;
      font-weight: 600;
      color: #333;
    }

    .close-btn {
      flex-shrink: 0;
      display: flex;
      align-items: center;
      justify-content: center;
      width: 60rpx;
      height: 60rpx;
      background: #f5f5f5;
      border-radius: 50%;
      transition: all 0.3s;

      &:active {
        background: #e8e8e8;
        transform: scale(0.9);
      }
    }
  }

  .session-list {
    flex: 1;
    padding: 12rpx 0;
    overflow-y: auto;
    overflow-x: hidden;

    // 滚动条样式（仅H5生效）
    &::-webkit-scrollbar {
      width: 4rpx;
    }

    &::-webkit-scrollbar-thumb {
      background: rgba(0, 0, 0, 0.1);
      border-radius: 4rpx;
    }

    &::-webkit-scrollbar-track {
      background: transparent;
    }

    .session-group {
      margin-bottom: 24rpx;

      .group-title {
        padding: 16rpx 20rpx 8rpx;
        font-size: 24rpx;
        font-weight: 500;
        color: #999;
        letter-spacing: 0.5rpx;
        line-height: 1.2;
      }

      .session-item {
        position: relative;
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 24rpx 20rpx;
        margin: 0 12rpx 12rpx;
        background-color: #fff;
        border-radius: 16rpx;
        box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06);
        transition: all 0.3s ease;

        &:active {
          transform: scale(0.98);
          box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08);
        }

        &.active {
          background: linear-gradient(135deg, #e8f4f3 0%, #f0f9f8 100%);
          box-shadow: 0 2rpx 12rpx rgba(5, 202, 182, 0.15), inset 0 0 0 2rpx #05cab6;

          .session-title {
            color: #05cab6;
            font-weight: 600;
          }
        }

        .session-content {
          flex: 1;
          display: flex;
          flex-direction: column;
          gap: 8rpx;
          overflow: hidden;
          min-width: 0;

          .session-title {
            font-size: 28rpx;
            font-weight: 500;
            color: #333;
            line-height: 1.5;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
          }

          .session-time {
            font-size: 22rpx;
            color: #999;
            font-weight: 400;
            line-height: 1.2;
          }
        }

        .delete-btn {
          flex-shrink: 0;
          display: flex;
          align-items: center;
          justify-content: center;
          width: 60rpx;
          height: 60rpx;
          margin-left: 12rpx;
          background: #fff5f5;
          border-radius: 12rpx;
          transition: all 0.3s;

          &:active {
            background: #ffe5e5;
            transform: scale(0.9);
          }
        }
      }
    }

    .empty-state {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      padding: 150rpx 40rpx;

      .empty-icon {
        display: flex;
        align-items: center;
        justify-content: center;
        margin-bottom: 20rpx;
        opacity: 0.8;
      }

      .empty-text {
        font-size: 28rpx;
        font-weight: 500;
        color: #666;
        margin-bottom: 8rpx;
      }

      .empty-desc {
        font-size: 24rpx;
        color: #999;
      }
    }
  }
}

.top-bg {
  background: url('/static/images/user/my-header-bg.png') no-repeat;
  background-size: 100% 100%;
}

// 头部
.header {
  z-index: 1000;
  display: flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  padding: 16rpx 32rpx;
  padding-top: calc(var(--status-bar-height) + 16rpx);

  .header-content {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;

    .title-wrapper {
      flex: 1;
      display: flex;
      flex-direction: row;
      align-items: center;
      gap: 16rpx;

      .header-title {
        font-size: 40rpx;
        font-weight: 700;
        color: #1a1a1a;
        letter-spacing: 0.5rpx;
        line-height: 1.2;
      }

      .usage-badge {
        display: inline-flex;
        align-items: center;
        padding: 6rpx 16rpx;
        background: linear-gradient(135deg, rgba(0, 212, 170, 0.1) 0%, rgba(0, 194, 153, 0.15) 100%);
        border: 1rpx solid rgba(0, 212, 170, 0.3);
        border-radius: 20rpx;

        .usage-text {
          font-size: 22rpx;
          font-weight: 500;
          color: #00d4aa;
          line-height: 1;
        }
      }
    }

    .new-session-btn {
      flex-shrink: 0;
      display: flex;
      align-items: center;
      justify-content: center;
      width: 56rpx;
      height: 56rpx;
      background: linear-gradient(135deg, #00d4aa 0%, #00c299 100%);
      border-radius: 50%;
      box-shadow: 0 4rpx 16rpx rgba(0, 212, 170, 0.3);
      transition: all 0.3s ease;

      &:active {
        transform: scale(0.92);
        box-shadow: 0 2rpx 12rpx rgba(0, 212, 170, 0.4);
      }

      .new-session-icon {
        width: 32rpx;
        height: 32rpx;
        filter: brightness(0) invert(1); // 将图标变为白色
      }
    }
  }
}

// 促销横幅
.banner {
  margin: 20rpx 30rpx;

  .banner-content {
    height: 220rpx;
    background: url('/static/images/home/banner.png') no-repeat;
    background-size: 100% 100%;
  }
}

// AI介绍容器
.ai-intro-container {
  margin: 30rpx;
}

// AI 助手区域
.ai-assistant {
    user-select: text; // 允许文本选择
    -webkit-user-select: text; // WebKit 内核浏览器
    -moz-user-select: text; // Firefox
    -ms-user-select: text; // IE/Edge
  padding: 30rpx;
  border-radius: 20rpx;

  .assistant-header {
    display: flex;
    align-items: center;
    margin-bottom: 20rpx;

    .robot-avatar {
      width: 60rpx;
      height: 60rpx;
      margin-right: 16rpx;
    }

    .assistant-name {
      font-size: 32rpx;
      font-style: italic;
      font-weight: 600;
      color: #2d3436;
    }
  }

  .assistant-message {
    padding: 24rpx;
    margin-bottom: 24rpx;
    cursor: pointer;
    background-color: #fff;
    border-radius: 16rpx;
    transition: all 0.3s ease;

    &:active {
      background-color: #f8f9fa;
      transform: scale(0.98);
    }

    .message-text {
      font-size: 28rpx;
      line-height: 1.5;
      color: #2d3436;
    }
  }

  .action-buttons {
    display: flex;
    gap: 16rpx;

    .action-btn {
      display: flex;
      flex: 1;
      align-items: center;
      justify-content: center;
      padding: 16rpx 20rpx;
      background: #fff;
      border-radius: 12rpx;

      .btn-icon {
        width: 28rpx;
        height: 28rpx;
        margin-right: 8rpx;
      }

      .btn-text {
        font-size: 26rpx;
        font-weight: 500;
        color: #05cab6;
      }
    }
  }
}


// 消息项
.message-item {
  margin-bottom: 30rpx;
}

// 消息包装器
.message-wrapper {
  display: flex;
  align-items: flex-end;
  padding: 0 30rpx;

  &.user-message {
    justify-content: flex-end;
  }

  &.ai-message {
    justify-content: flex-start;
  }
}

// 头像
.avatar {
  flex-shrink: 0;
  width: 60rpx;
  height: 60rpx;
  border-radius: 50%;
}

.user-avatar {
  margin-left: 20rpx;
}

.ai-avatar {
  margin-right: 20rpx;
}

// 消息内容
.message-content {
  max-width: 500rpx;
  padding: 20rpx 24rpx;
  word-wrap: break-word;
  border-radius: 20rpx;

  .message-text {
    font-size: 28rpx;
    line-height: 1.5;
    color: #333;
  }

  // rich-text 样式
  .message-rich-text {
    font-size: 28rpx;
    line-height: 1.6;
    color: #333;
    word-wrap: break-word;
    word-break: break-word;
  }

  // 可选择文本样式
  .message-selectable-text {
    display: block;
    font-size: 28rpx;
    line-height: 1.6;
    color: #333;
    word-wrap: break-word;
    word-break: break-word;
    white-space: pre-wrap; // 保留换行和空格
    user-select: text; // 允许文本选择
    -webkit-user-select: text; // WebKit 内核浏览器
    -moz-user-select: text; // Firefox
    -ms-user-select: text; // IE/Edge

    // 格式化的 Markdown 样式
    &.markdown-formatted {
      line-height: 1.8;

      // 这里可以添加更多 Markdown 样式
      // 但由于 uni-app 的 text 组件不支持复杂样式
      // 主要依赖格式化后的文本本身的可读性
    }
  }
}

// 用户消息样式
.user-content {
  position: relative;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border-bottom-right-radius: 8rpx;

  .message-text {
    color: #fff;
  }

  &.history-message {
    background: linear-gradient(135deg, #95a5a6 0%, #7f8c8d 100%);
    opacity: 0.8;
  }

  .history-tag {
    position: absolute;
    top: -8rpx;
    right: -8rpx;
    padding: 2rpx 8rpx;
    background-color: rgba(255, 255, 255, 0.9);
    border-radius: 8rpx;

    .history-text {
      font-size: 20rpx;
      color: #666;
    }
  }
}

// AI消息样式
.ai-content {
  position: relative;
  background-color: #fff;
  border: 1rpx solid #e9ecef;
  border-bottom-left-radius: 8rpx;
  box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.06);

  &.history-message {
    background-color: #f8f9fa;
    border-color: #dee2e6;
    opacity: 0.8;
  }

  .ai-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 8rpx;

    .ai-name {
      font-size: 24rpx;
      font-weight: 600;
      color: #667eea;
    }

    .typing-indicator {
      font-size: 22rpx;
      font-style: italic;
      color: #999;
    }

    .history-tag {
      padding: 2rpx 8rpx;
      background-color: #e9ecef;
      border-radius: 8rpx;

      .history-text {
        font-size: 20rpx;
        color: #666;
      }
    }
  }
}

// AI 分析容器样式
.ai-analysis-container {
  display: flex;
  flex-direction: column;
  gap: 24rpx;

  .analysis-header {
    padding-bottom: 16rpx;
    border-bottom: 2rpx solid #e9ecef;

    .analysis-title {
      font-size: 30rpx;
      font-weight: 600;
      color: #333;
    }
  }

  .analysis-section {
    display: flex;
    flex-direction: column;
    gap: 12rpx;
    padding: 20rpx;
    background-color: #f8f9fa;
    border-radius: 12rpx;

    .section-title {
      font-size: 28rpx;
      font-weight: 600;
      color: #667eea;
      margin-bottom: 8rpx;
    }

    .label {
      font-weight: 600;
      color: #666;
    }

    .info-item {
      display: block;
      font-size: 26rpx;
      line-height: 1.6;
      color: #333;
      margin-bottom: 8rpx;
    }

    .positive {
      color: #10b981;
      font-weight: 600;
    }

    .negative {
      color: #ef4444;
      font-weight: 600;
    }
  }

  // 趋势分析样式
  .trend-info {
    display: flex;
    flex-direction: column;
    gap: 8rpx;
  }

  .reasons {
    display: flex;
    flex-direction: column;
    gap: 12rpx;
    margin-top: 8rpx;

    .reason-title {
      font-size: 26rpx;
      font-weight: 600;
      color: #666;
      margin-bottom: 4rpx;
    }

    .reason-item {
      display: flex;
      flex-direction: column;
      gap: 4rpx;
      padding: 12rpx;
      background-color: #fff;
      border-radius: 8rpx;

      .reason-label {
        font-size: 26rpx;
        font-weight: 600;
        color: #667eea;
      }

      .reason-content {
        font-size: 24rpx;
        line-height: 1.6;
        color: #666;
      }
    }
  }

  // 价格信息样式
  .price-info {
    display: flex;
    flex-direction: column;
    gap: 8rpx;
  }

  // 交易建议样式
  .plan-card {
    display: flex;
    flex-direction: column;
    gap: 12rpx;
    padding: 16rpx;
    background-color: #fff;
    border: 2rpx solid #667eea;
    border-radius: 12rpx;
    margin-top: 12rpx;

    .plan-header {
      padding-bottom: 12rpx;
      border-bottom: 1rpx solid #e9ecef;

      .plan-title {
        font-size: 28rpx;
        font-weight: 600;
        color: #667eea;
      }
    }

    .plan-content {
      display: flex;
      flex-direction: column;
      gap: 10rpx;

      .plan-item {
        display: block;
        font-size: 26rpx;
        line-height: 1.6;
        color: #333;

        .reason {
          color: #999;
          font-size: 24rpx;
        }
      }

      .targets {
        display: flex;
        flex-direction: column;
        gap: 6rpx;

        .target-item {
          padding-left: 20rpx;
          font-size: 24rpx;
          color: #666;
          line-height: 1.6;
        }
      }
    }
  }

  // 风险提示样式
  .risk-section {
    background-color: #fef2f2;
    border-left: 4rpx solid #ef4444;

    .section-title {
      color: #ef4444;
    }

    .risk-item {
      display: flex;
      flex-direction: column;
      gap: 4rpx;
      padding: 12rpx;
      background-color: #fff;
      border-radius: 8rpx;
      margin-bottom: 8rpx;

      .risk-label {
        font-size: 26rpx;
        font-weight: 600;
        color: #ef4444;
      }

      .risk-content {
        font-size: 24rpx;
        line-height: 1.6;
        color: #666;
      }
    }
  }
}

// 加载动画
.loading-dots {
  display: flex;
  gap: 8rpx;
  align-items: center;

  .dot {
    width: 12rpx;
    height: 12rpx;
    background-color: #667eea;
    border-radius: 50%;
    animation: loading-bounce 1.4s ease-in-out infinite both;

    &:nth-child(1) {
      animation-delay: -0.32s;
    }

    &:nth-child(2) {
      animation-delay: -0.16s;
    }

    &:nth-child(3) {
      animation-delay: 0;
    }
  }
}

@keyframes loading-bounce {
  0%,
  80%,
  100% {
    opacity: 0.5;
    transform: scale(0);
  }

  40% {
    opacity: 1;
    transform: scale(1);
  }
}

// 欢迎消息
.welcome-message {
  display: flex;
  justify-content: center;
  padding: 60rpx 30rpx;
}

.welcome-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 60rpx 40rpx;
  background: linear-gradient(135deg, rgba(102, 126, 234, 0.1) 0%, rgba(118, 75, 162, 0.1) 100%);
  border: 1rpx solid rgba(102, 126, 234, 0.2);
  border-radius: 30rpx;

  .welcome-avatar {
    width: 120rpx;
    height: 120rpx;
    margin-bottom: 30rpx;
  }

  .welcome-title {
    margin-bottom: 16rpx;
    font-size: 36rpx;
    font-weight: 600;
    color: #333;
  }

  .welcome-desc {
    margin-bottom: 40rpx;
    font-size: 28rpx;
    line-height: 1.5;
    color: #666;
    text-align: center;
  }
}

// 快捷问题
.quick-questions {
  display: flex;
  flex-direction: column;
  gap: 20rpx;
  width: 100%;
}

.quick-question-btn {
  padding: 24rpx 32rpx;
  background-color: #fff;
  border: 1rpx solid #e9ecef;
  border-radius: 32rpx;
  transition: all 0.3s ease;

  &:active {
    background-color: #f8f9fa;
    transform: scale(0.98);
  }

  .question-text {
    font-size: 26rpx;
    font-weight: 500;
    color: #667eea;
    text-align: center;
  }
}

// 深色模式支持
@media (prefers-color-scheme: dark) {
  .page-container {
    background-color: #1a1a1a;
  }

  .header {
    background-color: #2d2d2d;
    border-bottom-color: #3d3d3d;
  }

  .ai-content {
    background-color: #2d2d2d;
    border-color: #3d3d3d;
  }
}

/* ==================== Markdown 渲染样式 ==================== */

/* rich-text 容器 */
.message-rich-text {
  font-size: 28rpx;
  line-height: 1.6;
  color: #333;
  word-wrap: break-word;
  word-break: break-all;
}

/* 代码块容器 */
.message-rich-text .code-wrapper {
  position: relative;
  margin: 16rpx 0;
  background-color: #1e1e1e;
  border-radius: 8rpx;
  overflow: hidden;
}

/* 代码语言标签 */
.message-rich-text .code-language {
  padding: 8rpx 16rpx;
  background-color: #2d2d2d;
  color: #858585;
  font-size: 24rpx;
  border-bottom: 1rpx solid #3d3d3d;
}

/* 代码复制按钮 */
.message-rich-text .code-copy-btn-inline {
  position: absolute;
  top: 8rpx;
  right: 8rpx;
  padding: 8rpx;
  color: #858585;
  font-size: 32rpx;
  cursor: pointer;
  z-index: 10;
}

.message-rich-text .code-copy-btn-inline:hover {
  color: #fff;
}

/* 代码块 */
.message-rich-text .code-block {
  margin: 0;
  padding: 16rpx;
  background-color: #1e1e1e;
  overflow-x: auto;
  font-family: 'Courier New', Courier, monospace;
  font-size: 24rpx;
  line-height: 1.5;
  color: #d4d4d4;
}

/* 代码高亮样式 */
.message-rich-text .hljs {
  display: block;
  overflow-x: auto;
  padding: 0;
  background: transparent;
  color: #d4d4d4;
}

/* 关键字 */
.message-rich-text .hljs-keyword,
.message-rich-text .hljs-selector-tag,
.message-rich-text .hljs-literal,
.message-rich-text .hljs-section,
.message-rich-text .hljs-link {
  color: #569cd6;
}

/* 字符串 */
.message-rich-text .hljs-string {
  color: #ce9178;
}

/* 注释 */
.message-rich-text .hljs-comment {
  color: #6a9955;
  font-style: italic;
}

/* 数字 */
.message-rich-text .hljs-number {
  color: #b5cea8;
}

/* 函数 */
.message-rich-text .hljs-function,
.message-rich-text .hljs-title {
  color: #dcdcaa;
}

/* 变量 */
.message-rich-text .hljs-variable,
.message-rich-text .hljs-attr {
  color: #9cdcfe;
}

/* 内联代码 */
.message-rich-text .inline-code {
  padding: 4rpx 8rpx;
  background-color: #f5f5f5;
  border-radius: 6rpx;
  font-family: 'Courier New', Courier, monospace;
  font-size: 24rpx;
  color: #e83e8c;
}

/* 粗体 */
.message-rich-text strong {
  font-weight: 600;
  color: #333;
}

/* 斜体 */
.message-rich-text em {
  font-style: italic;
  color: #666;
}

/* 链接 */
.message-rich-text a {
  color: #667eea;
  text-decoration: underline;
}

/* 可选择文本样式 */
.message-selectable-text {
  font-size: 28rpx;
  line-height: 1.6;
  color: #333;
  word-wrap: break-word;
  word-break: break-all;
  white-space: pre-wrap;
  user-select: text;
  -webkit-user-select: text;
}
</style>

